home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
simula
/
books
/
books.lha
/
kirkerud
/
postoffice.sim
< prev
next >
Wrap
Text File
|
1993-08-16
|
8KB
|
234 lines
% ****************************************************************
% * *
% * This is the program constructed in section 14.8 of *
% * Object Oriented Programming with Simula by Bj|rn Kirkerud; *
% * *
% ****************************************************************
external class settools;
settools begin
element class customer(arrival_time); real arrival_time;
begin
real length_of_service, start_of_service_time;
Boolean procedure will_join_queue(queue_length); integer queue_length;
will_join_queue := queue_length <= randint(0, 15, seed);
procedure service_starts(time); real time;
start_of_service_time := time;
Boolean procedure errand_done(time); real time;
errand_done := time ge start_of_service_time + length_of_service;
real procedure wait_time;
wait_time := start_of_service_time - arrival_time;
procedure display;
begin
outtext("Anonymous customer arrived at time ");
outfix(arrival_time, 1, 6);
outtext(", with length of service-time ");
outfix(length_of_service, 1, 6); outtext(" seconds.");
outimage;
end;
length_of_service := normal(105, 30, seed);
end of customer;
class counter(counter_number); integer counter_number;
begin
ref(customer) current_customer;
ref(sequence) the_queue;
integer total_number_of_customers,
max_queue_length;
real sum_idle_time,
start_idle_time,
sum_service_time,
sum_wait_time;
procedure arrive(a_customer); ref(customer) a_customer;
if current_customer == none
then begin
current_customer :- a_customer;
a_customer.service_starts(a_customer.arrival_time);
sum_idle_time := sum_idle_time +
a_customer.arrival_time - start_idle_time;
end
else begin
the_queue.append(a_customer);
max_queue_length := max(max_queue_length, the_queue.size);
end;
integer procedure number_of_customers;
number_of_customers := if current_customer == none then 0
else 1 + the_queue.size;
procedure check_current_customer(time); real time;
if current_customer =/= none and then current_customer.errand_done(time)
then current_customer_leaves;
procedure current_customer_leaves;
begin real time;
time := current_customer.start_of_service_time +
current_customer.length_of_service;
sum_service_time := sum_service_time +
current_customer.length_of_service;
sum_wait_time := sum_wait_time + current_customer.wait_time;
total_number_of_customers := total_number_of_customers + 1;
if the_queue.is_empty
then begin current_customer :- none; start_idle_time := time end
else begin
current_customer :- the_queue.head;
current_customer.service_starts(time);
the_queue :- the_queue.tail;
end;
end;
procedure day_is_over;
while current_customer =/= none do current_customer_leaves;
procedure write_statistics;
begin
outint(counter_number, 4);
outint(total_number_of_customers, 11);
outfix(sum_service_time, 1, 13);
outfix(sum_idle_time, 1, 9);
outint(max_queue_length, 6);
outimage;
end;
procedure display;
begin
outtext("Counter "); outint(counter_number, 0);
if current_customer =/= none then
begin
outtext(" is currently serving "); current_customer.display;
if the_queue.is_empty then User_message( "Empty queue.")
else begin
User_message( "A queue with the following customers:");
the_queue.display;
end;
end
else User_message(" is currently serving no customer");
end;
! Initialization: ;
the_queue :- new sequence;
end of counter;
class post_office(number_of_counters); integer number_of_counters;
begin
ref(counter) array the_counters(1 : number_of_counters);
integer customers_lost;
procedure arrive(a_customer); ref(customer) a_customer;
begin
integer counter_number, min_queue_length, counter_with_min_queue;
min_queue_length := maxint;
for counter_number := 1 step 1 until number_of_counters do
begin
the_counters(counter_number).
check_current_customer( a_customer.arrival_time);
if the_counters(counter_number).
number_of_customers < min_queue_length then
begin
min_queue_length := the_counters(counter_number).
number_of_customers;
counter_with_min_queue := counter_number;
end;
end;
if a_customer.will_join_queue(min_queue_length)
then the_counters(counter_with_min_queue).arrive(a_customer)
else customers_lost := customers_lost + 1;
end of arrive;
procedure day_is_over;
begin integer counter_number;
for counter_number := 1 step 1 until number_of_counters do
the_counters(counter_number).day_is_over;
end;
procedure write_statistics;
begin
real sum_service_time, sum_wait_time;
integer total_number_of_customers, counter_number;
User_message("Counter Number of Service Idle Max");
User_message("number customers time time queue");
for counter_number := 1 step 1 until number_of_counters do
begin
the_counters(counter_number).write_statistics;
sum_service_time := sum_service_time +
the_counters(counter_number) .sum_service_time;
sum_wait_time := sum_wait_time +
the_counters(counter_number).sum_wait_time;
total_number_of_customers := total_number_of_customers +
the_counters(counter_number) .total_number_of_customers;
end;
outtext("Total number of customers served: ");
outint(total_number_of_customers, 0); outimage;
outtext("Number of customers lost: ");
outint(customers_lost, 0); outimage;
outtext("Total service time: ");
outint(sum_service_time, 0); outtext(" seconds"); outimage;
outtext("Average wait time: ");
outint(sum_wait_time/total_number_of_customers, 0);
outtext(" seconds"); outimage;
end;
procedure display;
begin integer counter_number;
User_message("Post office status:");
for counter_number := 1 step 1 until number_of_counters do
the_counters(counter_number).display;
end;
! Initialize the counters: ;
begin integer counter_number;
for counter_number := 1 step 1 until number_of_counters do
the_counters(counter_number) :- new counter(counter_number);
end;
end of post_office;
procedure User_message(message); text message;
begin outtext(message); outimage end;
integer number_of_counters;
integer seed;
seed := 123795;
for number_of_counters := 1, 2, 3, 4, 5 do
begin
inspect new post_office(number_of_counters) do
begin
inspect new infile("poff.dta") do
begin
open(blanks(80));
while not lastitem do
arrive(new customer(inreal));
close;
end;
day_is_over;
write_statistics; outimage;
end;
end;
end of program;